import java.sql.SQLOutput;
import java.util.Arrays;

import static java.util.Arrays.binarySearch;

public class Main {

    //数组的创建
    public static void main1(String[] args) {
        int [] array1 = {1,2,3,4};

        int [] array2 = new int[] {1,2,3,4};

        int a = 10;
        int [] array3 = new int[a];
    }

    public static void main2(String[] args) {
        int[] array = {2,3,6,7,8,9};
        System.out.println(array[2]);

        array[1] = 520;
        System.out.println(array[1]);
        System.out.println(array.length);//获取数组的长度
    }

    //遍历数组的三种方式
    public static void main3(String[] args) {
        int [] array = {2,4,5,6,7};
        //第一种使用for循环
        for(int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
        System.out.println("---------------");

        //第二种
        for(int x : array) {
            System.out.println(x);
        }
        System.out.println("----------------");

        //第三种变成字符串
        String str = Arrays.toString(array);
        System.out.println(str);
    }

    //null数组
    public static void main4(String[] args) {
        int [] array = null;
        System.out.println(array);
        System.out.println(array.length); //null数组没有长度
    }

    //引用变量
    public static void main5(String[] args) {
        int [] array1 = new int[3];
        array1 [0] = 10;
        array1 [1] = 20;
        array1 [2] = 30;

        int [] array2 = new int[]{1,2,3,4,5};
        array2 [0] = 100;
        array2 [1] = 200;

        array1 = array2;

        array1 [2] = 300;
        array1 [3] = 400;
        array1 [4] = 500;
        for (int i = 0; i < array2.length; i++) {
            System.out.println(array2[i]);
        }
    }

    //作为函数的参数
    public static void main6(String[] args) {
        int [] arr = {1,2,3};
        fun(arr);
        System.out.println("arr[0] = " + arr[0]);
    }
    public static void fun(int[] args) {
        args[0] = 20;
        System.out.println("a[0] = " + args[0]);
    }

    //作为函数的返回值
    //使用数组获取斐波那契数列的前N项
    public static int[] fib(int n) {
        int [] array = new int[n];
        array[0] = array[1] = 1;
        for(int i = 2; i < n; i++) {
            array[i] = array[i - 1] + array[i - 2];
        }
        return array;
    }

    public static void main7(String[] args) {
        int [] array = fib(3);
        for(int i = 0; i < array.length; i++){
            System.out.println(array[i]);
        }
    }

    //数组转字符串
    public static void main8(String[] args) {
        int [] array = {1,2,3,4,5,6};
        String string = Arrays.toString(array);
        System.out.println(string);
    }

    //模拟Arrays.toString(array)
    public static void main9(String[] args) {
        int [] array = {1,2,3,4,5,6};
        String string = mytoString(array);
        System.out.println(string);
    }
    public static String mytoString(int[] arr) {
        String str = "[";
        for(int i = 0;i < arr.length; i++) {
            str = str + arr[i];
            if(i != arr.length-1) {
                str = str + ",";
            }
        }
        str = str + "]";
        return  str;
    }

    //数组拷贝 copyOf
    public static void main10(String[] args) {
        int [] array = {1,2,3,4,5};
        int [] copy = copyof(array);
        System.out.println(Arrays.toString(array));
    }

    public static int[] copyof(int[] arr) {
        int [] copy = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            copy[i] = arr[i];
        }
        return copy;
    }

    //数组拷贝Arrays.copyOf和Arrays.copyOfRange
    public static void main11(String[] args) {
        int [] arr = {1,2,3,4,5,6,7,8,9};
        int [] copy1 = Arrays.copyOf(arr,arr.length);
        System.out.println(Arrays.toString(copy1));
        System.out.println("--------------------");

        int [] copy2 = Arrays.copyOf(arr,2*arr.length);//使数组变成两倍
        System.out.println(Arrays.toString(copy2));
        System.out.println("-----------------------");

        int [] copy3 = Arrays.copyOfRange(arr,2,5);//复制数组的第2到第五个
        System.out.println(Arrays.toString(copy3));
    }

    //求数组的平均值
    public static void main12(String[] args) {
        int [] arr = {1,2,3,4,5,6};
        int sum = 0;
        for(int x : arr){
            sum += x;
        }
        System.out.println(sum * 1.0 / arr.length);//*1.0 让平均值可以有小数点
    }

    //Arrays.fill可以快速填充数组
    public static void main13(String[] args) {
        int [] arr = new int[10];
        Arrays.fill(arr,0,10,-1); //左关右开
        System.out.println(Arrays.toString(arr));
    }

    //Arrays.equals(array1,array2);判断两个数组是否相等
    public static void main14(String[] args) {
        int [] arr1 = {1,2,3,4,5};
        int [] arr2 = {1,2,3,4,5};

        boolean flg = Arrays.equals(arr1,arr2);
        System.out.println(flg);
    }

    //查找数组中指定元素(二分查找)
    public static void main15(String[] args) {
        int[] arr = {1, 2, 4, 5, 6, 7, 8, 9, 10};
        int target = myBinarySearch(arr, 3);
        System.out.println(target); // 输出 -1，因为3不在数组中
    }

    /**
     * 二分查找算法
     * @param arr 已排序的数组
     * @param n 要查找的目标值
     * @return 目标值在数组中的索引，若不存在则返回-1
     */
    public static int myBinarySearch(int[] arr, int n) {
        int left = 0;
        int right = arr.length - 1;

        // 当左指针小于等于右指针时，继续查找
        while (left <= right) {
            // 计算中间位置，使用这种方式可以避免整数溢出
            int mid = left + (right - left) / 2;

            if (n < arr[mid]) {
                // 目标值在左侧，调整右指针
                right = mid - 1;
            } else if (n > arr[mid]) {
                // 目标值在右侧，调整左指针
                left = mid + 1;
            } else {
                // 找到目标值，返回索引
                return mid;
            }
        }

        // 循环结束仍未找到，返回-1
        return -1;
    }
    //Java中二分查找可以使用binarySearch(arr, 6）
    public static void main17(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        System.out.println(binarySearch(arr, 6));
    }

    //模拟冒泡排序
    public static int[] myBubble(int[] arr) {
        for(int i = 0; i < arr.length; i++) {
            for(int j = 0; j < arr.length - 1 -i; j++){
                if(arr[j] > arr[j + 1]) {
                    int tmp = 0;
                    tmp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = tmp;
                }
            }
        }
        return arr;
    }

    public static void main18(String[] args) {
        int [] arr = {2,3,1,6,4,7,8,8};
        myBubble(arr);
        System.out.println(Arrays.toString(arr));
    }

    //可以使用Java中的Arrays.sort(arr);来排序
    public static void main19(String[] args) {
        int [] arr = {1,3,4,6,7,8,};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
    //数组逆序
    public static void main20(String[] args) {
        int [] arr = {1,2,3,4,5,6};

        int left = 0;
        int right = arr.length - 1;
        while(left < right){
            int tmp = arr[left];
            arr[left] = arr[right];
            arr[right] = tmp;
            left++;
            right--;
        }
        System.out.println(Arrays.toString(arr));
    }

    //二维数组
    public static void main21(String[] args) {
        int[][] arr = {{1,2,3},{2,3,4}};
        int[][] array2 = new int[][]{{1,2,3},{4,5,6}};
        int[][] array3 = new int[2][3];
    }

    //遍历二维数组
    public static void main22(String[] args) {
        int[][] arr = {{1,2,3},{2,3,4}};
        //第一种方式for循环
        for(int i = 0; i <2; i++){
            for(int j = 0; j < 3; j++){
                System.out.println(arr[i][j]);
            }
        }
        System.out.println("---------------");

        //第二种方式
        for(int[] tmp : arr) {
            for(int x : tmp){
                System.out.println(x);
            }
        }
    }
}